﻿using Fast.DependencyInjection.Attributes;
using Fast.DependencyInjection.Dependencies;
using Fast.FriendlyException;
using Fast.UnifyResult.Attributes;
using Fast.UnifyResult.Internal;
using Fast.UnifyResult.Options;
using Fast.UnifyResult.Providers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Fast.Web.Core.Provider
{
    /// <summary>
    /// 自定义 RESTful 风格返回值
    /// </summary>
    //[SuppressSniffer, UnifyModel(typeof(RESTfulResult<>))]
    public class RESTfulResultProvider : ITransient, IUnifyResultProvider
    {
        public RESTfulResultProvider()
        {
        }

        public IActionResult OnAuthorizeException(DefaultHttpContext context, ExceptionMetadata metadata)
        {
            throw new NotImplementedException();
        }

        public IActionResult OnSucceeded(ActionExecutedContext context, object data)
        {
            // 正常返回成功的数据，返回统一格式的成功响应
            return new JsonResult(JsonConvert.SerializeObject(RESTfulResult(StatusCodes.Status200OK, true, data)));
        }

        public IActionResult OnValidateFailed(ActionExecutingContext context, ValidationMetadata metadata)
        {
            // 验证失败返回
            var errors = new List<string> { "Validation failed" };
            return new JsonResult(RESTfulResult(StatusCodes.Status400BadRequest, false, null, errors));
        }

        public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
        {
            // 异常返回
            return new JsonResult(RESTfulResult(metadata.StatusCode, false, metadata.Data, metadata.Errors));
        }

        public async Task OnResponseStatusCodes(HttpContext context, int statusCode, UnifyResultSettingsOptions unifyResultSettings)
        {
            // 特定状态码返回
            var result = RESTfulResult(statusCode, false, null, "An error occurred");
            context.Response.StatusCode = statusCode;
            await context.Response.WriteAsJsonAsync(result);
        }

        public static RESTfulResult<object> RESTfulResult(int statusCode, bool succeeded = default, object data = default, object errors = default)
        {
            return new RESTfulResult<object>
            {
                StatusCode = statusCode,
                Succeeded = succeeded,
                Data = data,
                Errors = errors,
                Extras = "",
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
            };
        }
    }
}
